<template>
  <div class="container">
    <div class="row">
      <div class="text-wrap">
        <h1 :style="{ '--background': background }">
          {{ text }}
        </h1>
      </div>
      <input v-model="text" placeholder="请输入" class="text-input" type="text" />
    </div>
    <CodeEditor :code="textCode" type="css"></CodeEditor>
    <div class="box" :style="{ background: background }"></div>
    <div class="row">
      <label class="label" for="width">选择宽度: </label>
      <input
        v-model="boxWidth"
        name="width"
        type="range"
        min="0"
        max="100"
        step="1"
        id="width"
        :data-value="boxWidth + '%'"
      />
    </div>
    <div class="row">
      <label class="label" for="height">选择高度: </label>
      <input
        v-model="boxHeight"
        name="height"
        type="range"
        min="0"
        max="300"
        step="1"
        id="height"
        :data-value="boxHeight + 'px'"
      />
    </div>
    <CodeEditor :code="backgroundCode" type="css"></CodeEditor>
    <div class="row">
      <label class="label" for="director">选择方向: </label>
      <TabButton v-model="radio" :options="options" @change="handleCodeChange"></TabButton>
    </div>
    <div class="row">
      <label class="label" for="angle">选择角度: </label>
      <input
        v-model="angle"
        name="angle"
        :disabled="radio === 'radial'"
        type="range"
        min="0"
        max="360"
        step="1"
        id="angle"
        :data-value="angle + '°'"
        @input="handleCodeChange"
      />
    </div>
    <TabButton v-model="angle" :options="angleOptions" @change="handleCodeChange"></TabButton>
    <div class="row">
      <IconButton icon="plus" @click="handleClick('add')"></IconButton>
      <IconButton icon="minus" @click="handleClick('remove')"></IconButton>
      <IconButton icon="reset" @click="handleClick('reset')"></IconButton>
    </div>
    <ColorEditor
      v-for="(value, index) in colorList"
      :key="index"
      v-bind="{ value, index }"
      @update="handleCodeChange"
    ></ColorEditor>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, onMounted } from 'vue'
import CodeEditor from '@/components/CodeEditor/index.vue'
import { codeGenerator } from '@/utils/gradient'
import { hex2rgb, formatRGB } from '@/utils/tools'
import TabButton from '@/components/TabButton.vue'
import IconButton from '@/components/IconButton.vue'
import ColorEditor from '@/components/ColorEditor.vue'

const options = ref<any[]>([
  {
    label: '线性渐变',
    value: 'linear'
  },
  {
    label: '径向渐变',
    value: 'radial'
  },
  {
    label: '锥形渐变',
    value: 'conic'
  }
])
const angleOptions = ref<any[]>([
  {
    label: '向右',
    value: 90
  },
  {
    label: '向下',
    value: 180
  },
  {
    label: '向左',
    value: 270
  },
  {
    label: '向上',
    value: 0
  }
])
const text = ref<string>('测试文字')
const textCode = ref<string>(codeGenerator('linear-gradient(90deg, #ffffff, #000000)'))
const backgroundCode = ref<string>('linear-gradient(90deg, #ffffff, #000000);')
const colorList = ref<any[]>([
  {
    color: '#cb2d3e',
    opacity: 100
  },
  {
    color: '#ef473a',
    opacity: 100
  }
])
const radio = ref<string>('linear')
const angle = ref<number>(90)
const boxWidth = ref<number>(100)
const boxHeight = ref<number>(100)

// function
const changeRBG = ({ color, opacity }: any) => {
  let result = color
  if (+opacity < 100) {
    let rgb = hex2rgb(color)
    result = formatRGB([...rgb, +opacity / 100])
  }
  return result
}
const handleCodeChange = () => {
  backgroundCode.value = background.value + ';'
  textCode.value = codeGenerator(background.value)
}
const handleClick = (behavior: string) => {
  let colorListValue = colorList.value
  switch (behavior) {
    case 'add':
      colorListValue.push({
        color: '#FFFFFF',
        opacity: 100
      })
      break
    case 'remove':
      colorListValue.length > 2 && colorListValue.pop()
      break
    case 'reset':
      colorList.value = [
        {
          color: '#FFFFFF',
          opacity: 100
        },
        {
          color: '#000000',
          opacity: 100
        }
      ]
      break
    default:
      break
  }
  handleCodeChange()
}

// 计算属性
const background = computed(() => {
  let gradient: string = colorList.value.map((item) => changeRBG(item)).join(', ')
  let background: string = ''
  switch (radio.value) {
    case 'linear':
      background = `linear-gradient(${angle.value}deg, ${gradient})`
      break
    case 'radial':
      background = `radial-gradient(${gradient})`
      break
    case 'conic':
      background = `conic-gradient(from ${angle.value}deg, ${gradient})`
      break
    default:
      break
  }
  return background
})

onMounted(() => {
  handleCodeChange()
})
</script>

<style lang="scss" scoped>
.container {
  h1 {
    font: 28px '楷体';
    background: var(--background);
    background-clip: text;
    -webkit-background-clip: text;
    color: transparent;
    font-weight: bold;
    display: inline-block;
    vertical-align: middle;
    white-space: nowrap;
    line-height: 1.8;
  }
  .text-wrap {
    width: 100%;
    overflow: hidden;
    overflow-x: auto;
    display: inline-block;
  }

  .text-input {
    position: relative;
    font-size: 16px;
    height: auto;
    padding: 10px;
    width: 100%;
    line-height: 1.428571429;
    vertical-align: middle;
    border: 1px solid #cccccc;
    border-radius: 4px;
    box-shadow: inset 0 1px 1px rgb(0 0 0 / 8%);
    transition: border-color .2s cubic-bezier(.645,.045,.355,1);

    &:focus,
    &:focus-visible {
      outline: none;
      border-color: #409eff;
    }
  }

  .box {
    --width: v-bind(boxWidth);
    --height: v-bind(boxHeight);
    width: calc(var(--width) * 1%);
    height: calc(var(--height) * 1px);
  }

  .label {
    font-weight: 700;
    color: #001f3f;
    color: var(--textColor);
    white-space: nowrap;
    display: inline-block;
    padding-right: 10px;
    line-height: 2;
  }

  > div:not(:last-child) {
    margin-bottom: 16px;
  }
}
</style>
